package com.wangyb.wework.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.utils.http.HttpUtils;
import com.wangyb.wework.entity.CorpEntity;
import com.wangyb.wework.entity.agent.WwAgent;
import com.wangyb.wework.utils.crypt.AccessToken;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

import static com.wangyb.wework.common.WxApiConst.*;

/**
 * @Author: wangyb
 * @Date: 2021/6/28 10:46 上午
 */
@Component
public class WxTokenUtils {
	private static final Logger log = LoggerFactory.getLogger(WxTokenUtils.class);
	private static Map<String, AccessToken> map = new HashMap<>(0);
	private static Map<String,JsApiTicket> TICKET_MAP = new HashMap<>();


	/**
	 * 获取 accessToken
	 *
	 * @param wxCorpId 企业微信 id
	 * @param secret   业务相关 secret
	 * @return accessToken
	 */
	private static synchronized AccessToken getAccessToken(String wxCorpId, String secret) {
		String respJson = HttpUtils.sendGet(API_ACCESS_TOKEN,"corpid=" + wxCorpId + "&corpsecret=" + secret);
		log.error("getAccessToken: " + respJson);

		JSONObject jsonObject = JSON.parseObject(respJson);
		int errCode = jsonObject.getIntValue("errcode");
		if (errCode == 0) {
			AccessToken token = new AccessToken();
			token.setAccessToken(jsonObject.getString("access_token"));
			token.setExpiresIn(jsonObject.getLong("expires_in"));
			return token;
		}
		return null;
	}

	/**
	 * 获取通讯录相关 accessToken, 优先从缓存中获取
	 *
	 * @param corpId 企业 id
	 * @return accessToken
	 */
	public static synchronized String getAccessTokenEmployee(Long corpId) {
		CorpEntity corpEntity = getCorpEntity(corpId);
		String keyAccess = "emp-" + corpId;
		AccessToken accessToken = map.get(keyAccess);
		if (accessToken == null || accessToken.isExpired()) {
			accessToken = getAccessToken(corpEntity.getWxCorpId(),corpEntity.getEmployeeSecret());
			map.put("emp-" + corpId, accessToken);
		}
		return accessToken.getAccessToken();
	}

	/**
	 * 获取通讯录相关 accessToken, 直接获取新的
	 *
	 * @param corpId 企业 id
	 * @return accessToken
	 */
	public static synchronized String getNewAccessTokenEmployee(Long corpId) {
		CorpEntity corpEntity = getCorpEntity(corpId);
		String wxCorpId = corpEntity.getWxCorpId();
		String employSecret = corpEntity.getEmployeeSecret();
		AccessToken accessToken = getAccessToken(wxCorpId, employSecret);
		map.put("emp-" + corpId, accessToken);
		return accessToken.getAccessToken();
	}

	/**
	 * 获取企业微信自建应用相关 accessToken, 优先从缓存中获取
	 *
	 * @param agent 应用 id
	 * @return accessToken
	 */
	public static String getAccessTokenAgent(Long corpId, WwAgent agent) {
		String keyAccess = "agent-" + agent.getId();
		AccessToken accessToken = map.get(keyAccess);
		if (accessToken == null || accessToken.isExpired()) {
			accessToken = getNewAccessTokenAgent(corpId, agent);
		}
		return accessToken.getAccessToken();
	}

	/**
	 * 获取企业微信自建应用相关 accessToken, 直接获取新的
	 *
	 * @param corpId 企业id
	 * @param agent 应用
	 * @return accessToken
	 */
	public static AccessToken getNewAccessTokenAgent(Long corpId, WwAgent agent) {
		CorpEntity corpEntity = getCorpEntity(corpId);
		String wxCorpId = corpEntity.getWxCorpId();
		String wxSecret = agent.getWxSecret();
		AccessToken accessToken = getAccessToken(wxCorpId, wxSecret);
		map.put("agent-" + agent.getId(), accessToken);
		return accessToken;
	}

	/**
	 * 获取客户相关 accessToken, 优先从缓存中获取
	 *
	 * @param corpId 企业 id
	 * @return accessToken
	 */
	public static synchronized String getAccessTokenContact(Long corpId) {
		String keyAccess = "con-" + corpId;
		CorpEntity corpEntity = getCorpEntity(corpId);
		AccessToken accessToken = map.get(keyAccess);
		if (accessToken == null || accessToken.isExpired()) {
			accessToken = getAccessToken(corpEntity.getWxCorpId(),corpEntity.getContactSecret());
			map.put("con-" + corpId, accessToken);
		}
		return accessToken.getAccessToken();
	}


	/**
	 * 获取客户相关 accessToken, 直接获取新的
	 *
	 * @param corpId 企业 id
	 * @return accessToken
	 */
	public static synchronized String getNewAccessTokenContact(Long corpId) {
		CorpEntity corpEntity = getCorpEntity(corpId);
		String wxCorpId = corpEntity.getWxCorpId();
		String secret = corpEntity.getContactSecret();
		AccessToken accessToken = getAccessToken(wxCorpId, secret);
		map.put("con-" + corpId, accessToken);
		return accessToken.getAccessToken();
	}

	/**
	 * 获取企业的jsapi_ticket
	 * @param corpId
	 * @return
	 */
	public static synchronized String getJsapiTicketOfCorp(Long corpId) {
		String ticketKey = "corp-" + corpId + "-ticket";
		JsApiTicket ticket = TICKET_MAP.get(ticketKey);
		if (ticket == null || ticket.isExpired()) {
			ticket = getNewJsapiTicketOfCorp(corpId);
			TICKET_MAP.put(ticketKey,ticket);
		}
		return ticket.getTicket();
	}

	/**
	 * 获取企业的jsapi_ticket,直接获取新的
	 * @param corpId
	 * @return
	 */
	public static synchronized JsApiTicket getNewJsapiTicketOfCorp(Long corpId) {
		String accessToken = getAccessTokenContact(corpId);
		String respJson = HttpUtils.sendGet(API_GET_JSAPI_TICKET_CORP,"access_token=" + accessToken);
		JSONObject jsonObject = JSON.parseObject(respJson);
		int errCode = jsonObject.getIntValue("errcode");
		if (errCode == 0) {
			JsApiTicket ticket = new JsApiTicket();
			ticket.setTicket(jsonObject.getString("ticket"));
			ticket.setExpiresIn(jsonObject.getLong("expires_in"));
			return ticket;
		}
		return null;
	}
	public static String getJsapiTicketOfAgent(Long corpId, WwAgent agent) {
		String ticketKey = "corp-" + corpId + "-ticket-" + agent.getId() + "-app";
		JsApiTicket ticket = TICKET_MAP.get(ticketKey);
		if (ticket == null || ticket.isExpired()) {
			ticket = getNewJsapiTicketOfAgent(corpId, agent);
			TICKET_MAP.put(ticketKey,ticket);
		}
		return ticket.getTicket();
	}

	public static JsApiTicket getNewJsapiTicketOfAgent(Long corpId, WwAgent agent) {
		String accessToken = getAccessTokenAgent(corpId,agent);
		String respJson = HttpUtils.sendGet(API_GET_JSAPI_TICKET_APP,"access_token=" + accessToken + "&type=agent_config");
		JSONObject jsonObject = JSON.parseObject(respJson);
		int errCode = jsonObject.getIntValue("errcode");
		if (errCode == 0) {
			JsApiTicket ticket = new JsApiTicket();
			ticket.setTicket(jsonObject.getString("ticket"));
			ticket.setExpiresIn(jsonObject.getLong("expires_in"));
			return ticket;
		}
		return null;
	}
	/**
	 * 获取企业信息
	 *
	 * @param corpId 企业 Id
	 * @return 企业实体
	 */
	public static CorpEntity getCorpEntity(Long corpId) {
		CorpEntity corpEntity = new CorpEntity();
		corpEntity.setWxCorpId("ww3f8336aef6eaf606");
		corpEntity.setEmployeeSecret("cVq-9TwJORS74KXGOLWQSbJ-9GxUjzW14XdFHq-o3n8");
		corpEntity.setContactSecret("CHcx4aueIHf2r2PHdY1fueMBRgnfk1XS2dH71_ZRC5M");
		corpEntity.setEncodingAesKey("YzQ2NjIxMTYzYTBiNDQ2MTgzOTYzMDYwZWJlNTBiOWY");

		//TODO token怎么获取?
		corpEntity.setToken("a850c361e05be355fb654930bec81686");
		return corpEntity;
	}
}
